const std = @import("std");

pub fn build(b: *std.Build) !void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const ver_tag = std.SemanticVersion{ .major = 2024, .minor = 1, .patch = 13 };
    const ver_tag_str: []const u8 = try std.fmt.allocPrint(std.heap.page_allocator, "\"{}-{}-{}\"", .{ ver_tag.major, ver_tag.minor, ver_tag.patch });

    std.debug.print("quickjs version: {s}\r\n", .{ver_tag_str});

    // option for pthread
    var pthread_on = b.option(bool, "pthread", "enable pthread support, windows platform force it on") orelse true;

    if (target.query.os_tag == .windows) {
        pthread_on = true;
    }

    // quickjs C source
    const upstream = b.dependency("quickjs", .{});

    // zquickjs library
    const lib = b.addSharedLibrary(.{
        .name = "zquickjs",
        .version = ver_tag,
        .target = target,
        .optimize = optimize,
    });
    lib.linkLibC();
    lib.addIncludePath(upstream.path(""));
    lib.addCSourceFiles(.{
        .root = upstream.path(""),
        .files = &.{
            "quickjs.c",
            "libregexp.c",
            "libunicode.c",
            "cutils.c",
            "quickjs-libc.c",
            "libbf.c",
        },
        .flags = &.{
            "-DCONFIG_BIGNUM",
        },
    });
    lib.defineCMacro("CONFIG_VERSION", ver_tag_str);

    if (pthread_on) {
        std.debug.print("zquickjs: pthread is on\r\n", .{});
        const upstream_pthread = b.dependency("winpthreads", .{ .target = target, .optimize = optimize });
        lib.linkLibrary(upstream_pthread.artifact("winpthreads"));
        lib.addIncludePath(upstream_pthread.path("inlcude"));
    }
    // lib header files
    lib.step.dependOn(&b.addInstallHeaderFile(upstream.path("quickjs-atom.h"), "quickjs-atom.h").step);
    lib.step.dependOn(&b.addInstallHeaderFile(upstream.path("quickjs-libc.h"), "quickjs-libc.h").step);
    lib.step.dependOn(&b.addInstallHeaderFile(upstream.path("quickjs.h"), "quickjs.h").step);
    b.installArtifact(lib);

    // qjsc binary
    const exe = b.addExecutable(.{
        .name = "zqjsc",
        .version = ver_tag,
        .optimize = optimize,
        .target = target,
    });
    exe.addIncludePath(upstream.path(""));
    exe.addCSourceFiles(.{
        .root = upstream.path(""),
        .files = &.{
            "qjsc.c",
        },
        .flags = &.{
            "-DCONFIG_BIGNUM",
            // "-DCONFIG_VERSION=" + ver_tag_str,
        },
    });
    exe.defineCMacro("CONFIG_VERSION", ver_tag_str);

    exe.linkLibC();
    exe.linkLibrary(lib);

    if (pthread_on) {
        std.debug.print("zqjsc: pthread is on\r\n", .{});
        const upstream_pthread = b.dependency("winpthreads", .{ .target = target, .optimize = optimize });
        exe.linkLibrary(upstream_pthread.artifact("winpthreads"));
        exe.addIncludePath(upstream_pthread.path("inlcude"));
    }
    b.installArtifact(exe);
}
